#include <QtCore\QFile>
#include <QtCore\QTextStream>
#include <QtGui\QKeyEvent>
#include "editor\MaterialEditor.h"
#include "editor\ConfigFile.h"
#include "MaterialEditor.ui.h"

MaterialEditor::MaterialEditor(QWidget* parent)
  : QWidget(parent),
    mpForm(new Ui::MaterialEditor)
{
  mpForm->setupUi(this);
  mpForm->editorStatusBar->setSizeGripEnabled(false);

  mKeywordSyntaxesItr = mKeywordSyntaxes.end();

  connect (mpForm->txtEditor, SIGNAL(keywordChanged(QString, QString)),
           this, SLOT(onKeywordChanged(QString, QString)));
  connect (mpForm->txtEditor, SIGNAL(keyPressed(QKeyEvent*)),
           this, SLOT(onEditorKeyEvent(QKeyEvent*)));
}


MaterialEditor::~MaterialEditor(void)
{
}

void MaterialEditor::onKeywordChanged(QString keyword, QString format)
{
  // See if this is a valid keyword for this format
  const config::FormatWordMap& words = 
    config::ConfigFile::instance()->getWordsByFormat(format);
  
  setKeyword(keyword, format);
}

void MaterialEditor::onEditorKeyEvent(QKeyEvent* e)
{
  // CTRL+Up or CTRL+Down : Change which keyword syntax is displayed
  if (e->modifiers() & Qt::ControlModifier &&
      mKeywordSyntaxesItr != mKeywordSyntaxes.end())
  {
    if (e->key() == Qt::Key_Up)
    {
      // Advance the iterator
      ++mKeywordSyntaxesItr;
      if (mKeywordSyntaxesItr == mKeywordSyntaxes.end())
        mKeywordSyntaxesItr = mKeywordSyntaxes.begin();
    }
    else if (e->key() == Qt::Key_Down)
    {
      // Decrease the iterator
      if (mKeywordSyntaxesItr != mKeywordSyntaxes.begin())
        --mKeywordSyntaxesItr;
      else
        mKeywordSyntaxesItr = (mKeywordSyntaxes.end() - 1);
    }

    mpForm->editorStatusBar->showMessage(*mKeywordSyntaxesItr);
  }
}

void MaterialEditor::setKeyword(QString keyword, QString format)
{
  const config::FormatWordMap& words = 
    config::ConfigFile::instance()->getWordsByFormat(format);

  // Clear the current status
  mpForm->editorStatusBar->clearMessage();

  // Clear any existing syntaxes
  mKeywordSyntaxes.clear();
  
  config::FormatWordMap::const_iterator citr = words.find(keyword);
  if (citr != words.end())
  {
    QString docFile = citr->doc;
    const QString& manualPath = config::ConfigFile::instance()->getManualPath();
      
    QFile file(manualPath + docFile);
    if (file.open(QFile::ReadOnly | QFile::Text))
    {
      QTextStream stream(&file);
      QString text = stream.readAll();
      file.close();

      
      // Probably never going to be 4 different formats, but just to be sure...
      for (int i = 0; i < 4; ++i)
      {
        // Look for the string "Format: <keyword>"
        QString pattern = QString("Format%1: %2 ")
                          .arg((i==0) ? "" : QString::number(i))
                          .arg(keyword);
        QStringMatcher matcher(pattern);
        int index = matcher.indexIn(text);
        if (index >= 0)
        {
          // Look for the first <BR> after the format.
          matcher.setPattern("<BR>");
          int endIndex = matcher.indexIn(text, index);
          if (endIndex >= 0)
          {
            // The syntax is between the two indices.
            QString syntax = text.mid(index, endIndex-index);

            // Format the synatx properly
            syntax.replace("&lt;", "<");
            syntax.replace("&gt;", ">");

            // Add to the keyword syntax vector
            mKeywordSyntaxes.push_back(syntax);
          }
        }
      }
    }
  }

  // Point to the first syntax
  mKeywordSyntaxesItr = mKeywordSyntaxes.begin();

  // If there is at least one valid syntax, show the first one
  if (mKeywordSyntaxesItr != mKeywordSyntaxes.end())
    mpForm->editorStatusBar->showMessage(*mKeywordSyntaxesItr);
}